/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 *
 * This file is part of retabel.
 *
 * Copyright (c) 2011 by individual contributors as indicated by the
 * @author tags. See the copyright.txt file in the distribution
 * for a full listing of individual contributors.
 *
 * This is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 */

package org.retabel.web.rest;

import org.retabel.persistence.entity.document.DocumentConfiguration;
import org.retabel.service.manager.DocumentConfigurationManager;
import org.retabel.service.mapper.XmlDocumentConfigurationMapper;
import xsd.documentconfigurations.DocumentConfigurationList;
import xsd.documentconfigurations.DocumentConfigurations;
import xsd.documentconfigurations.ObjectFactory;

import javax.ejb.EJB;
import javax.ejb.Stateless;
import javax.ws.rs.*;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo;
import javax.xml.bind.JAXBElement;

/**
 * Document configuration REST interface implementation
 * <p/>
 * <h3>Extra-Info</h3>
 * Created: 10:19 16.07.11
 *
 * @author Peter Herber
 * @version 1.0
 */
@Path("/config/document/")
@Stateless
public class DocumentConfigurationServiceBean extends RestServiceBean {

    /** The document configuration manager. */
    @EJB
    private DocumentConfigurationManager documentConfigurationManager;

    /** The configuration mapper. */
    @EJB
    private XmlDocumentConfigurationMapper xmlDocumentConfigurationMapper;


    /**
     * Returns a set of document configurations.
     *
     * @param first index of the first item.
     * @param maxRows maximum number of items to be returned.
     * @return a set of document configurations.
     */
    @GET
    @Produces(MediaType.TEXT_XML)
    public Response getDocumentConfigurations(@QueryParam("first") Integer first,
                                                                         @QueryParam("maxRows") Integer maxRows) {
        int maxRowsWithFallback = maxRows != null ? maxRows : getDefaultMaxResultsPerPage();
        int firstWithFallback = first != null ? first : 0;

        int countReportDesigns = documentConfigurationManager.count();
        DocumentConfiguration[] documentConfigurations = documentConfigurationManager.findAllSorted(firstWithFallback,
                                                                                                    maxRowsWithFallback);

        ObjectFactory of = new ObjectFactory();

        DocumentConfigurations result = of.createDocumentConfigurations();
        result.setStart(firstWithFallback);
        result.setRows(documentConfigurations.length);
        result.setCount(countReportDesigns);

        DocumentConfigurationList documentConfigurationList = of.createDocumentConfigurationList();
        result.setList(documentConfigurationList);

        for (DocumentConfiguration documentConfiguration : documentConfigurations) {
            xsd.documentconfigurations.DocumentConfiguration resultDocumentConfiguration = of.createDocumentConfiguration();
            resultDocumentConfiguration.setName(documentConfiguration.getName());
            resultDocumentConfiguration.setVersion(documentConfiguration.getVersion());

            documentConfigurationList.getDocumentConfiguration().add(resultDocumentConfiguration);
        }

        return Response.ok(result).build();
    }

    /**
     * Method to receive an store a document configuration.
     *
     * @param data a xml document that contains the configuration.
     * @param uriInfo the url info.
     * @return logging response.
     */
    @POST
    @Consumes(MediaType.APPLICATION_XML)
    @Produces(MediaType.TEXT_PLAIN)
    public Response postDocumentConfiguration(byte[] data, @Context UriInfo uriInfo) {
        PlainTextResponseBuilder response = new PlainTextResponseBuilder(uriInfo);

        response.println("Attempting to store document configuration ...");

        try {
            response.println("xmlData: [" + data.length + "]");
            documentConfigurationManager.store(data);
        } catch (Exception e) {
            response.println(e.toString());
            return response.getServerErrorResponse();
        }

        return response.getResponse();
    }

    /**
     * Returns a specific document configuration, identified by name and version.
     *
     * @param name name of the document configuration.
     * @param version version of the document configuration.
     * @return the document configuration.
     */
    @GET
    @Path("/{name}/{version}")
    @Produces(MediaType.TEXT_XML)
    public Response getDocumentConfiguration(@PathParam("name") String name, @PathParam(
        "version") String version) {

        DocumentConfiguration documentConfiguration = documentConfigurationManager.findDocumentConfiguration(name, version);

        if (documentConfiguration == null) {
            return Response.status(Response.Status.NOT_FOUND).build();
        }

        return Response.ok(xmlDocumentConfigurationMapper.marshal(documentConfiguration).getValue()).build();
    }

    /**
     * Deletes a document configuration, identified by name and version.
     *
     * @param name name of the document configuration.
     * @param version version of the document configuration.
     * @param uriInfo the UriInfo.
     * @return a logging response.
     */
    @DELETE
    @Path("/{name}/{version}")
    @Produces(MediaType.TEXT_PLAIN)
    public Response deleteDocumentConfiguration(@PathParam("name") String name, @PathParam("version") String version,
                                                @Context UriInfo uriInfo) {
        PlainTextResponseBuilder response = new PlainTextResponseBuilder(uriInfo);

        response.println("Deleting document configuration: " + name + " [" + version + "]");

        documentConfigurationManager.remove(name, version);

        return response.getResponse();
    }
}
